"""
Copyright (c) 2008 Rune M. Friborg, runef@diku.dk.
See LICENSE.txt for licensing details (GPLv2).
"""

import wx            
from plugins.system import *

class PluginManagerBUILDER(PluginManager):
        
    def __init__(self):
        PluginManager.__init__(self, 'BUILDER')
        
    def load(self):

        import plugins.builder.workspaces
        plugins.builder.workspaces.load(self)

        import plugins.builder.multiplier
        plugins.builder.multiplier.load(self)

        import plugins.builder.broadcast
        plugins.builder.broadcast.load(self)

        import plugins.builder.icon
        plugins.builder.icon.load(self)

        import plugins.builder.codeeditor
        plugins.builder.codeeditor.load(self)

        import plugins.builder.setup
        plugins.builder.setup.load(self)

        import plugins.builder.executeenv
        plugins.builder.executeenv.load(self)

        import plugins.builder.forknjoin
        plugins.builder.forknjoin.load(self)
        
        # new: loading cspshare plugin
        import plugins.builder.cspshareplugin
        plugins.builder.cspshareplugin.load(self)
        
    def prefmenu(self, frame, menu):
        for p in self.plugins:
            p.prefmenu(frame, menu)
        
    def rcmenu(self, location_def, frame, menu, o):
        for p in self.plugins:
            p.rcmenu(location_def, frame, menu, o)

    def dcmenu(self, location_def, frame, o):
        for p in self.plugins:
            p.dcmenu(location_def, frame, o)
   
    def loadAttr(self, node_def, att, D):
        for p in self.plugins:
            D = p.loadAttr(node_def, att, D)
        return D

    def setAttr(self, node_def, node, D):
        for p in self.plugins:
            p.setAttr(node_def, node, D)

    def draw(self, location_def, layer, dc, o, position, selected):
        for p in self.plugins:
            p.draw(location_def, layer, dc, o, position, selected)

    def drawComponentInfo(self, dialog, cspData):
        for p in self.plugins:
            p.drawComponentInfo(dialog, cspData)

    def drawLeftBar(self, mainFrame):
        for p in self.plugins:
            p.drawLeftBar(mainFrame)
        leftSizer = mainFrame.leftPanel.GetSizer()
        leftSizer.Add(wx.StaticLine(mainFrame.leftPanel, -1, size=wx.Size(100, -1)), 0, wx.ALL | wx.ALIGN_CENTER, 5)


    def loadTags(self, node_def, node, D):
        for p in self.plugins:
            D = p.loadTags(node_def, node, D)
        return D

    def createTags(self, node_def, node, D):
        for p in self.plugins:
            node = p.createTags(node_def, node, D)
        return node

    def getList(self, list_def):
        L = []
        for p in self.plugins:
            L = p.getList(list_def, L)
        return L

    def executeOnStartup(self, frame):
        for p in self.plugins:
            p.executeOnStartup(frame)

    def updatePath(self, L):
        for p in self.plugins:
            L = p.updatePath(L)
        return L

    def onCreateConnection(self, src_obj, dst_obj):
        for p in self.plugins:
            p.onCreateConnection(src_obj, dst_obj)
            
    def drawInsertCompArea(self, location_def, sizer, dialog):
        for p in self.plugins:
            p.drawInsertCompArea(location_def, sizer, dialog)


class PluginBUILDER(Plugin):
    def __init__(self, manager, name):
        Plugin.__init__(self, manager, name)

    # Add
    def addPrefMenuElement(self, callback):
        '''
        Add an element to the preferences menu giving a callback method
        @param callback:
        '''
        menuid = self.manager.getID()
        self.addListCallback('PrefMenuElement', (callback, menuid))

    # Request
    def prefmenu(self, frame, menu):
        for (callback, menuid) in self.getListCallback('PrefMenuElement'):
            callback(frame, menu, menuid)

    # Add        
    def addRightClickElement(self, location_def, callback):
        menuid = self.manager.getID()
        self.addDictCallback('RightClickElement', location_def, (callback, menuid))

    # Request
    def rcmenu(self, location_def, frame, menu, o):
        for (callback, menuid) in self.getDictCallback('RightClickElement', location_def):
            callback(frame, menu, o, menuid)

    # Add
    def addDoubleClickElement(self, location_def, callback):
        self.addDictCallback('DoubleClickElement', location_def, callback)

    # Request
    def dcmenu(self, location_def, frame, o):
        for callback in self.getDictCallback('DoubleClickElement', location_def):
            callback(frame, o)

    # Add
    def addLeftBarElement(self, callback):
        self.addListCallback('LeftBarElement', callback)

    # Request
    def drawLeftBar(self, mainFrame):            
        leftSizer = mainFrame.leftPanel.GetSizer()
        for callback in self.getListCallback('LeftBarElement'):
            leftSizer.Add(wx.StaticLine(mainFrame.leftPanel, -1, size=wx.Size(120, -1)), 0, wx.ALL | wx.ALIGN_CENTER, 5)
            callback(mainFrame)

    # Add
    def addDrawElement(self, location_def, layer, callback):
        k = location_def + (100*layer)
        self.addDictCallback('DrawElement', k, callback)

    # Request
    def draw(self, location_def, layer, dc, o, offset, selected):
        k = location_def + (100*layer)
        for callback in self.getDictCallback('DrawElement', k):
            callback(dc, o, offset, selected)

    # Add
    def addComponentInfoElement(self, callback):
        self.addListCallback('ComponentInfoElement', callback)

    # Request
    def drawComponentInfo(self, dialog, cspData):            
        for callback in self.getListCallback('ComponentInfoElement'):
            callback(dialog, cspData)

    # Add
    def addCSPAttribute(self, node_def, attr_name, attr_type = None, attr_default = None, attr_check = None):
        a = (attr_name, attr_type, attr_default, attr_check)
        self.addDictCallback('CSPAttribute', node_def, a)
        
    # Request
    def loadAttr(self, node_def, att, D):
        for (attr_name, attr_type, attr_default, attr_check) in self.getDictCallback('CSPAttribute', node_def):
            val = cspxml.getAttr(att, attr_name)
            # Use default
            if (val == None):
                val = attr_default
            
            # Check val
            if ((not (attr_check == None)) and not attr_check(val)):
                # Check returned false
                pass
            else:
                # No check or check returned true
                if (not (attr_type == None)):
                    D[attr_name] = attr_type(val)
                else:
                    D[attr_name] = val
        return D

    # Request
    def setAttr(self, node_def, node, D):
        for (attr_name, attr_type, attr_default, attr_check) in self.getDictCallback('CSPAttribute', node_def):
            if D.has_key(attr_name):
                val = D[attr_name]
                # Check val
                if ((not (attr_check == None)) and not attr_check(val)):
                    # Check returned false
                    pass
                else:
                    # No check or check returned true
                    cspxml.setAttr(node, attr_name, val)



    # Request
    def loadTags(self, node_def, node, D):
        for (create_callback, load_callback) in self.getDictCallback('Tags', node_def):
            D = load_callback(node, D)
        return D

    # Request
    def createTags(self, node_def, node, D):
        for (create_callback, load_callback) in self.getDictCallback('Tags', node_def):
            node = create_callback(node, D)
        return node

    # Add
    def addCSPTag(self, node_def, create_callback, load_callback):
        e = (create_callback, load_callback)
        self.addDictCallback('Tags', node_def, e)

    # Request
    def getList(self, list_def, L):
        for callback in self.getDictCallback('List', list_def):
            L = callback(L)
        return L

    # Add
    def addList(self, list_def, callback):
        self.addDictCallback('List', list_def, callback)

    # Request
    def executeOnStartup(self, frame):
        for callback in self.getListCallback('ExecuteOnStartup'):
            callback(frame)

    # Add
    def addToExecuteOnStartup(self, callback):
        self.addListCallback('ExecuteOnStartup', callback)

    # Request
    def updatePath(self, L):
        for callback in self.getListCallback('UpdatePath'):
            L = callback(L)
        return L

    # Add
    def addUpdatePath(self, callback):
        self.addListCallback('UpdatePath', callback)

    # Request
    def onCreateConnection(self, src_obj, dst_obj):
        for callback in self.getListCallback('CreateConnection'):
            callback(src_obj, dst_obj)

    # Add
    def addToCreateConnection(self, callback):
        self.addListCallback('CreateConnection', callback)
        
    # NEW CALLBACK METHODS
    # Add
    def addDrawInsertCompArea(self, location_def, callback):
        '''
        
        @param location_def:
        @param callback:
        '''
        self.addDictCallback('DrawInsertCompArea', location_def, callback)

    # Request
    def drawInsertCompArea(self, location_def, sizer, dialog):
        '''
        Draw an area in the insert component dialog.
        @param location_def:
        @param sizer: The sizer in which the area should be drawn
        @param dialog: The insert component dialog
        '''
        for callback in self.getDictCallback('DrawInsertCompArea', location_def):
            callback(sizer, dialog)